﻿using Newtonsoft.Json;
using Rougamo.Context;
using System.Diagnostics;

namespace XC.Framework.Aop.Models
{
    public class TimeContext
    {
        /// <summary>
        /// 函数上下文
        /// </summary>
        public MethodContext? MethodContext { get; set; }

        /// <summary>
        /// 开始时间
        /// </summary>
        public DateTime StartTime { get; set; }

        /// <summary>
        /// 结束时间
        /// </summary>
        public DateTime EndTime { get; set; }

        /// <summary>
        /// 命名空间
        /// </summary>
        public string? NameSpace { get; set; }

        /// <summary>
        /// 类名称
        /// </summary>
        public string? ClassName { get; set; }

        /// <summary>
        /// 函数名称
        /// </summary>
        public string? MethodName { get; set; }

        /// <summary>
        /// 备注/描述
        /// </summary>
        public string? Remark { get; set; }

        /// <summary>
        /// 耗时
        /// </summary>
        public long ElapsedMilliseconds { get; set; }

        /// <summary>
        /// 定时器对象
        /// </summary>
        public Stopwatch? Stopwatch { get; set; }

        /// <summary>
        /// 返回值
        /// </summary>
        public object? ReturnValue { get; set; }

        /// <summary>
        /// 返回值类型名称
        /// </summary>
        public string? ReturnTypeName { get; set; }

        /// <summary>
        /// 函数入参参数
        /// </summary>
        public List<string> ParameterStr { get; set; }

        /// <summary>
        /// 函数入参值
        /// </summary>
        public List<object?>? ParameterValue { get; set; }

        /// <summary>
        /// 定义映射方法
        /// </summary>
        /// <param name="context"></param>
        /// <param name="remark"></param>
        /// <param name="stopwatch"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        public static TimeContext Map(MethodContext context, string remark, Stopwatch? stopwatch, DateTime endTime)
        {
            // 开始时间
            var startTime = context.Datas["StartTime"] is not null ? (DateTime?)context.Datas["StartTime"] : null;
            // 命名空间
            var nameSpace = context.Method.DeclaringType?.Namespace;
            // 类名
            var className = context.Method.DeclaringType?.Name;
            // 方法名
            var methodName = context.Method.Name;
            // 函数返回值
            var returnValue = context.ReturnValue == null ? null : JsonConvert.SerializeObject(context.ReturnValue);
            // 函数返回类型
            var returnType = context.RealReturnType?.Name;
            // 函数入参参数
            var parameters = context.Method.GetParameters().Select(s => s.ParameterType.Name + " " + s.Name).ToList();
            // 函数入参值
            var parameterValues = context.Arguments.Select(s => s?.ToString() ?? null);

            // 对象
            var timeContext = new TimeContext
            {
                MethodContext = context,
                StartTime = startTime ?? DateTime.Now,
                EndTime = endTime,
                NameSpace = nameSpace,
                ClassName = className,
                MethodName = methodName,
                Remark = remark,
                ElapsedMilliseconds = stopwatch?.ElapsedMilliseconds ?? 0,
                Stopwatch = stopwatch,
                ReturnValue = returnValue,
                ReturnTypeName = returnType,
                ParameterStr = parameters,
            };

            return timeContext;
        }

    }

}
